<!-- B2C商城交易分析 -->
<template>
	<div class="cost-wrap">
		<div class="module-box pb30">
			<div class="flex-between el-form-sub-title font-bold">交易概况</div>
			<div class="mb20 flex-between">
				<div>
					<span class="mr10">时间筛选</span>
					<el-date-picker
						v-model="dateRangeValue"
						type="daterange"
						unlink-panels
						range-separator="至"
						start-placeholder="开始时间"
						end-placeholder="结束时间"
						:disabled-date="disabledDate"
						:shortcuts="shortcuts"
						@change="handleDateChange"
					/>
				</div>
				<el-button type="primary" plain @click="onExport" v-auth="'data:b2c:mall:trade:analysis:export'">导出数据</el-button>
			</div>
			<div class="order-overview" v-loading="loading">
				<div class="flex relative">
					<div class="mr20">
						<div class="sub-title">
							下单笔数
							<el-tooltip class="box-item" effect="light" content="筛选时间内，成功下单的笔数(生成订单)，（不剔除退款订单）" placement="top">
								<el-icon color="#888" class="mt-3 ml5" style="vertical-align: middle">
									<QuestionFilled />
								</el-icon>
							</el-tooltip>
						</div>
						<div class="font20 mt10 mb5">{{ data.orderAll }}</div>
						<div :class="getColor(data.orderAllRate)">{{ data.orderAllRate }}</div>
					</div>
					<div class="mr20">
						<div class="sub-title">
							下单人数
							<el-tooltip
								class="box-item"
								effect="light"
								content="筛选时间内，成功下单的客户数(生成订单)，一人多次下单记为一人（不剔除退款订单）"
								placement="top"
							>
								<el-icon color="#888" class="mt-3 ml5" style="vertical-align: middle">
									<QuestionFilled />
								</el-icon>
							</el-tooltip>
						</div>
						<div class="font20 mt10 mb5">{{ data.orderAllUser }}</div>
						<div :class="getColor(data.orderAllUserRate)">{{ data.orderAllUserRate }}</div>
					</div>
					<div class="mr20">
						<div class="sub-title">
							下单金额
							<el-tooltip class="box-item" effect="light" content="筛选时间内，成功下单的订单金额（不剔除退款订单）" placement="top">
								<el-icon color="#888" class="mt-3 ml5" style="vertical-align: middle">
									<QuestionFilled />
								</el-icon>
							</el-tooltip>
						</div>
						<div class="font20 mt10 mb5">{{ fenToYuan(data.orderAllAmount) }}</div>
						<div :class="getColor(data.orderAllAmountRate)">{{ data.orderAllAmountRate }}</div>
					</div>
					<div class="mr20">
						<div class="sub-title">
							下单件数
							<el-tooltip class="box-item" effect="light" content="筛选时间内，成功下单的商品件数(不剔除退款订单)" placement="top">
								<el-icon color="#888" class="mt-3 ml5" style="vertical-align: middle">
									<QuestionFilled />
								</el-icon>
							</el-tooltip>
						</div>
						<div class="font20 mt10 mb5">{{ data.orderAllNums }}</div>
						<div :class="getColor(data.orderAllNumsRate)">{{ data.orderAllNumsRate }}</div>
					</div>
					<div class="absolute top25 font20" style="color: #fff; right: 18%">下单</div>
					<div class="absolute text-center" style="top: 115px; right: 2%">下单-支付<br />转化率<br />{{ data.changeRate }}</div>
				</div>
				<div class="flex mt20 relative">
					<div class="mr20">
						<div class="sub-title">
							支付订单数
							<el-tooltip
								class="box-item"
								effect="light"
								content="筛选时间内，成功支付的订单笔数，一个订单对应唯一一个订单号(不剔除退款订单)"
								placement="top"
							>
								<el-icon color="#888" class="mt-3 ml5" style="vertical-align: middle">
									<QuestionFilled />
								</el-icon>
							</el-tooltip>
						</div>
						<div class="font20 mt10 mb5">{{ data.orderPayAll }}</div>
						<div :class="getColor(data.orderPayAllRate)">{{ data.orderPayAllRate }}</div>
					</div>
					<div class="mr20">
						<div class="sub-title">
							支付人数
							<el-tooltip
								class="box-item"
								effect="light"
								content="筛选时间内，下单并且支付成功的客户数，一人多次付款记为一人(不剔除退款订单)"
								placement="top"
							>
								<el-icon color="#888" class="mt-3 ml5" style="vertical-align: middle">
									<QuestionFilled />
								</el-icon>
							</el-tooltip>
						</div>
						<div class="font20 mt10 mb5">{{ data.orderPayAllUser }}</div>

						<div :class="getColor(data.orderPayAllUserRate)">{{ data.orderPayAllUserRate }}</div>
					</div>
					<div class="mr20">
						<div class="sub-title">
							实际支付金额
							<el-tooltip class="box-item" effect="light" content="筛选时间内，成功支付订单去除优惠券得订单金额之和(不剔除退款)" placement="top">
								<el-icon color="#888" class="mt-3 ml5" style="vertical-align: middle">
									<QuestionFilled />
								</el-icon>
							</el-tooltip>
						</div>
						<div class="font20 mt10 mb5">{{ fenToYuan(data.orderPayAllAmount) }}</div>

						<div :class="getColor(data.orderPayAllAmountRate)">{{ data.orderPayAllAmountRate }}</div>
					</div>
					<div class="mr20">
						<div class="sub-title">
							支付件数
							<el-tooltip class="box-item" effect="light" content="筛选时间内，成功支付的商品件数之和(不剔除退款)" placement="top">
								<el-icon color="#888" class="mt-3 ml5" style="vertical-align: middle">
									<QuestionFilled />
								</el-icon>
							</el-tooltip>
						</div>
						<div class="font20 mt10 mb5">{{ data.orderPayAllNums }}</div>

						<div :class="getColor(data.orderPayAllNumsRate)">{{ data.orderPayAllNumsRate }}</div>
					</div>
					<div class="mr20">
						<div class="sub-title">
							复购率
							<el-tooltip class="box-item" effect="light" content="筛选时间内，回头客支付人数/总支付人数(不剔除退款订单)" placement="top">
								<el-icon color="#888" class="mt-3 ml5" style="vertical-align: middle">
									<QuestionFilled />
								</el-icon>
							</el-tooltip>
						</div>
						<div class="font20 mt10 mb5">{{ data.fugou }}</div>

						<div :class="getColor(data.fugouRate)">{{ data.fugouRate }}</div>
					</div>
					<div class="mr20">
						<div class="sub-title">
							客单价
							<el-tooltip class="box-item" effect="light" content="筛选时间内，支付金额/支付人数(不剔除退款订单)" placement="top">
								<el-icon color="#888" class="mt-3 ml5" style="vertical-align: middle">
									<QuestionFilled />
								</el-icon>
							</el-tooltip>
						</div>
						<div class="font20 mt10 mb5">{{ fenToYuan(data.kedan) }}</div>

						<div :class="getColor(data.kedanRate)">{{ data.kedanRate }}</div>
					</div>

					<div class="absolute font20" style="color: #fff; right: 18%; top: 70px">支付</div>
				</div>
				<div class="flex mt20">
					<div class="mr20">
						<div class="sub-title">
							退款订单数
							<el-tooltip class="box-item" effect="light" content="筛选时间内，支付成功后退款的订单数量" placement="top">
								<el-icon color="#888" class="mt-3 ml5" style="vertical-align: middle">
									<QuestionFilled />
								</el-icon>
							</el-tooltip>
						</div>
						<div class="font20 mt10 mb5">{{ data.orderRefund }}</div>

						<div :class="getColor(data.orderRefundRate)">{{ data.orderRefundRate }}</div>
					</div>
					<div class="mr20">
						<div class="sub-title">
							退款人数<el-tooltip class="box-item" effect="light" content="筛选时间内，支付成功后退款的人数" placement="top">
								<el-icon color="#888" class="mt-3 ml5" style="vertical-align: middle">
									<QuestionFilled />
								</el-icon>
							</el-tooltip>
						</div>
						<div class="font20 mt10 mb5">{{ data.orderRefundUser }}</div>

						<div :class="getColor(data.orderRefundUserRate)">{{ data.orderRefundUserRate }}</div>
					</div>
					<div class="mr20">
						<div class="sub-title">
							退款金额<el-tooltip class="box-item" effect="light" content="筛选时间内，包含优惠券的退款订单金额" placement="top">
								<el-icon color="#888" class="mt-3 ml5" style="vertical-align: middle">
									<QuestionFilled />
								</el-icon>
							</el-tooltip>
						</div>
						<div class="font20 mt10 mb5">{{ fenToYuan(data.orderRefundAmount) }}</div>

						<div :class="getColor(data.orderRefundAmountRate)">{{ data.orderRefundAmountRate }}</div>
					</div>
					<div class="mr20">
						<div class="sub-title">
							退款件数<el-tooltip class="box-item" effect="light" content="筛选时间内，退款的商品件数" placement="top">
								<el-icon color="#888" class="mt-3 ml5" style="vertical-align: middle">
									<QuestionFilled />
								</el-icon>
							</el-tooltip>
						</div>
						<div class="font20 mt10 mb5">{{ data.orderRefundNums }}</div>

						<div :class="getColor(data.orderRefundNumsRate)">{{ data.orderRefundNumsRate }}</div>
					</div>
					<div class="mr20">
						<div class="sub-title">
							退款率<el-tooltip class="box-item" effect="light" content="筛选时间内，退款订单数/支付订单数" placement="top">
								<el-icon color="#888" class="mt-3 ml5" style="vertical-align: middle">
									<QuestionFilled />
								</el-icon>
							</el-tooltip>
						</div>
						<div class="font20 mt10 mb5">{{ data.refund }}</div>

						<div :class="getColor(data.refundRate)">{{ data.refundRate }}</div>
					</div>
				</div>
			</div>
			<div class="chart-table mt20">
				<div class="el-form-sub-title font-bold">支付趋势图</div>
				<div class="line-chart-wrap" v-loading="loading">
					<LineCharts :option="payChartData" />
				</div>
			</div>
			<div class="chart-table mt20">
				<div class="el-form-sub-title font-bold">退款趋势图</div>
				<div class="line-chart-wrap" v-loading="loading">
					<LineCharts :option="returnChartData" />
				</div>
			</div>
		</div>
		<div class="module-box pb30 mt20">
			<div class="el-form-sub-title font-bold">交易构成</div>
			<div class="mb20 flex-between">
				<div>
					<span class="mr10">时间筛选</span>
					<el-date-picker
						v-model="constituteDateRangeValue"
						type="daterange"
						unlink-panels
						range-separator="至"
						start-placeholder="开始时间"
						end-placeholder="结束时间"
						:disabled-date="disabledDate"
						@change="handleConstituteDateChange"
					/>
				</div>
			</div>
			<div class="flex-between">
				<div class="pie-chart-table mr20">
					<div class="el-form-sub-title font-bold">交易客户构成</div>
					<div class="pie-chart-wrap" v-loading="constituteLoading">
						<PieCharts :option="pieChartData.data1" />
					</div>
				</div>
				<div class="pie-chart-table">
					<div class="el-form-sub-title font-bold">订单金额分布</div>
					<div class="pie-chart-wrap" v-loading="constituteLoading">
						<PieCharts :option="pieChartData.data2" />
					</div>
				</div>
			</div>
			<div class="flex-between mt20">
				<div class="pie-chart-table mr20">
					<div class="el-form-sub-title font-bold">支付渠道分析</div>
					<div class="pie-chart-wrap" v-loading="constituteLoading">
						<PieCharts :option="pieChartData.data3" />
					</div>
				</div>
				<div class="pie-chart-table">
					<div class="el-form-sub-title font-bold">支付用户类型分析</div>
					<div class="pie-chart-wrap" v-loading="constituteLoading">
						<PieCharts :option="pieChartData.data4" />
					</div>
				</div>
			</div>

			<ProTable :searchCol="{ xs: 1, sm: 2, md: 2, lg: 3, xl: 4 }" ref="proTable" :columns="columns" :data="constituteData">
				<template #expand="scope">
					{{ scope.row }}
				</template>
			</ProTable>
		</div>
	</div>
</template>

<script setup lang="tsx" name="dataCost">
import { onMounted, ref, reactive, computed } from 'vue';
import { ElMessage, ElMessageBox } from 'element-plus';
import { useRouter, useRoute } from 'vue-router';
import dayjs from 'dayjs';
import { NextLoading } from '/@/utils/loading';
import { fetchB2cOrderExport, fetchB2cOrder, fetchB2cOrderAmount } from '/@/api/data';
import { useDownload } from '/@/hooks/useDownload';
import LineCharts from '/@/components/chart/lineCharts.vue';
import PieCharts from '/@/components/chart/pieCharts.vue';

import { fenToYuan, scale2Format } from '/@/utils/commonFunction';
import ProTable from '/@/components/ProTable/index.vue';
import { ProTableInstance, ColumnProps } from '/@/components/ProTable/interface';

const router = useRouter();
const route = useRoute();

const dateRangeValue = ref([dayjs().subtract(30, 'day').format('YYYY-MM-DD'), dayjs().subtract(1, 'day').format('YYYY-MM-DD')]);
const constituteDateRangeValue = ref([dayjs().subtract(30, 'day').format('YYYY-MM-DD'), dayjs().subtract(1, 'day').format('YYYY-MM-DD')]);
const loading = ref(true);
const constituteLoading = ref(true);

const data = ref<any>({
	goodsAll: '--',
	goodsAllRate: '--',
	goodsOffline: '--',
	goodsOfflineRate: '--',
	goodsOnline: '--',
	goodsOnlineRate: '--',
	goodsOrder: '--',
	goodsOrderRate: '--',
	goodsOrderAmount: '--',
	goodsOrderAmountRate: '--',
	goodsOrderDetail: '--',
	goodsOrderDetailRate: '--',
	goodsPay: '--',
	goodsPayRate: '--',
	goodsPayAmount: '--',
	goodsPayAmountRate: '--',
	goodsPayDetail: '--',
	goodsPayDetailRate: '--',
	goodsRefund: '--',
	goodsRefundRate: '--',
	goodsRefundAmount: '--',
	goodsRefundAmountRate: '--',
	goodsRefundDetail: '--',
	goodsRefundDetailRate: '--',
});
const payChartData = reactive<any>({
	data: [],
	xData: [],
	legend: [
		{ name: '支付订单数', code: 'orderPayAll' },
		{ name: '支付人数', code: 'orderPayAllUser' },
		{ name: '实际支付金额', code: 'orderPayAllAmount', type: 'price' },
		{ name: '支付件数', code: 'orderPayAllNums' },
		{ name: '客单价', code: 'kedan', type: 'price' },
	],
});

const returnChartData = reactive<any>({
	data: [],
	xData: [],
	legend: [
		{ name: '退款订单数', code: 'orderRefund' },
		{ name: '退款人数', code: 'orderRefundUser' },
		{ name: '含券退款金额', code: 'orderRefundAmount', type: 'price' },
		{ name: '实际支付金额', code: 'orderPayAllAmount', type: 'price' },
		{ name: '退款件数', code: 'orderRefundNums' },
	],
});

const pieChartData = reactive<any>({
	data1: {
		data: [
			{
				value: 0,
				name: '新客支付',
				code: 'newAmount',
			},
			{
				value: 0,
				name: '老客支付',
				code: 'oldAmount',
			},
		],
	},
	data2: {
		data: [
			{
				value: 0,
				name: '0-500元',
				code: 'amountNums1',
			},
			{
				value: 0,
				name: '500-1000元',
				code: 'amountNums2',
			},
			{
				value: 0,
				name: '1000-3000元',
				code: 'amountNums3',
			},
			{
				value: 0,
				name: '3000-5000元',
				code: 'amountNums4',
			},
			{
				value: 0,
				name: '5000-8000元',
				code: 'amountNums5',
			},
			{
				value: 0,
				name: '8000-15000元',
				code: 'amountNums6',
			},
			{
				value: 0,
				name: '15000元以上',
				code: 'amountNums7',
			},
		],
		tooltipFormatter: (params: any) => {
			return `<div>
					${params.marker} ${params.name}<br/>
					<div class='font13 mt5' style='line-height: 24px'>
						订单笔数：${params.value}笔 <br/>
						订单占比：${scale2Format(params.data.proportion)}%
					</div>
				</div>`;
		},
		legendFormatter: (target: any) => {
			return `${target.name} ${target.value}笔 ${scale2Format(target.proportion)}%`;
		},
	},
	data3: {
		data: [
			{
				value: 0,
				name: '支付宝支付',
				code: 'alipayAmount',
			},
			{
				value: 0,
				name: '微信支付',
				code: 'wechatAmount',
			},
		],
	},
	data4: {
		data: [
			{
				value: 0,
				name: '个人用户支付',
				code: 'userPay',
			},
			{
				value: 0,
				name: '经销商用户支付',
				code: 'userDealerPay',
			},
		],
	},
});

const constituteData = ref<any>([]);

const shortcuts = [
	{
		text: '昨天',
		value: () => {
			const end = new Date();
			const start = new Date();
			start.setTime(start.getTime() - 3600 * 1000 * 24);
			return [start, end];
		},
	},
	{
		text: '近7天',
		value: () => {
			const end = new Date();
			const start = new Date();
			start.setTime(start.getTime() - 3600 * 1000 * 24 * 7);
			return [start, end];
		},
	},
	{
		text: '近30天',
		value: () => {
			const end = new Date();
			const start = new Date();
			start.setTime(start.getTime() - 3600 * 1000 * 24 * 30);
			return [start, end];
		},
	},
];

// 获取 ProTable 元素，调用其获取刷新数据方法（还能获取到当前查询参数，方便导出携带参数）
const proTable = ref<ProTableInstance>();

// 表格配置项
const columns: ColumnProps<any>[] = [
	{
		prop: 'name',
		label: '交易客户构成',
		minWidth: 120,
	},
	{
		prop: 'money',
		label: '支付金额',
		minWidth: 160,
	},
	{
		prop: 'moneyRate',
		label: '较上一周期',
		minWidth: 120,
	},
	{
		prop: 'num',
		label: '支付人数',
		minWidth: 120,
	},
	{
		prop: 'numRate',
		label: '较上一周期',
		minWidth: 120,
	},
];

const disabledDate = (time: Date) => {
	return time.getTime() > Date.now();
};

const handleDateChange = (val: any) => {
	getChartdata();
};

const handleConstituteDateChange = (val: any) => {
	getConstituteChartdata();
};

const getChartdata = async () => {
	loading.value = true;
	const params = {
		startTime: dayjs(dateRangeValue.value[0]).format('YYYY-MM-DD'),
		endTime: dayjs(dateRangeValue.value[1]).format('YYYY-MM-DD'),
	};
	payChartData.xData = [];
	payChartData.data = [];
	returnChartData.xData = [];
	returnChartData.data = [];
	const res: any = await fetchB2cOrder(params);
	data.value = res.data.data;
	payChartData.legend.map((i: any, index: number) => {
		const arr: any = [];
		res.data.chartsData.forEach((item: any) => {
			if (index == 0) {
				payChartData.xData.push(item.reportDate);
			}
			arr.push(i.type === 'price' ? fenToYuan(item[i.code]) : item[i.code]);
		});
		payChartData.data.push(arr);
	});
	returnChartData.legend.map((i: any, index: number) => {
		const arr: any = [];
		res.data.chartsData.forEach((item: any) => {
			if (index == 0) {
				returnChartData.xData.push(item.reportDate);
			}
			arr.push(i.type === 'price' ? fenToYuan(item[i.code]) : item[i.code]);
		});
		returnChartData.data.push(arr);
	});
	loading.value = false;
};

const getConstituteChartdata = async () => {
	constituteLoading.value = true;
	const params = {
		startTime: dayjs(constituteDateRangeValue.value[0]).format('YYYY-MM-DD'),
		endTime: dayjs(constituteDateRangeValue.value[1]).format('YYYY-MM-DD'),
	};
	try {
		const res: any = await fetchB2cOrderAmount(params);
		constituteLoading.value = false;
		Object.keys(pieChartData).forEach((key: any) => {
			pieChartData[key].data.forEach((element: any) => {
				element.value = res.data[element.code];
			});
		});
		constituteData.value = [
			{
				name: '新客支付',
				money: fenToYuan(res.data.newAmount),
				moneyRate: res.data.newAmountRate,
				num: res.data.newNums,
				numRate: res.data.newNumsRate,
			},
			{
				name: '老客支付',
				money: fenToYuan(res.data.oldAmount),
				moneyRate: res.data.oldAmountRate,
				num: res.data.oldNums,
				numRate: res.data.oldNumsRate,
			},
		];
	} catch (error) {
		constituteLoading.value = false;
	}
};

const handleParams = (params: any) => {
	let data = {
		...params,
	};

	return data;
};

const getColor = (str: string) => {
	const classStr = str ? (str == '增长0.00%' ? '' : str.includes('增长') ? 'grow-red' : str.includes('下降') ? 'grow—green' : '') : '';
	return classStr;
};

// 保存并导出
const onExport = () => {
	ElMessageBox.confirm('确认导出数据?', '温馨提示', { type: 'warning' }).then(() =>
		useDownload(fetchB2cOrderExport, '订单列表', {
			startTime: dayjs(dateRangeValue.value[0]).format('YYYY-MM-DD'),
			endTime: dayjs(dateRangeValue.value[1]).format('YYYY-MM-DD'),
		})
	);
};

// 页面加载时
onMounted(() => {
	NextLoading.done();
	getChartdata();
	getConstituteChartdata();
});
</script>

<style lang="scss">
.cost-wrap {
	.module-box {
		background: var(--el-color-white);
		padding: 20px;
		border-radius: var(--el-border-radius-round);
		box-sizing: border-box;
		.time {
			background: #f2f5f8;
			height: 32px;
			line-height: 32px;
			border-radius: 18px;
			font-size: 14px;
			font-weight: 400;
			padding: 0 16px;
			color: rgba($color: #000000, $alpha: 0.7);
			flex-shrink: 0;
		}
		.table-main {
			padding: 0;
		}
	}
	.sub-title {
		color: #666;
	}
	.grid {
		display: flex;
	}
	.grid-content {
		width: 20%;
	}
	.chart-table,
	.pie-chart-table {
		box-sizing: border-box;
		border: 1px solid #e6e6e6;
		border-radius: 4px;
		.el-form-sub-title {
			border-bottom: 1px solid #e6e6e6;
			padding: 15px 20px;
		}
	}
	.pie-chart-table {
		width: 50%;
	}
	.line-chart-wrap {
		height: 300px;
		width: 100%;
		padding: 0 20px 10px;
	}
	.pie-chart-wrap {
		height: 300px;
		width: 100%;
	}
	.order-overview {
		padding: 10px;
		background: url('../../../../assets/images/deal_bg.png') no-repeat;
		background-size: 96% 100%;
		.flex > .mr20 {
			width: calc(12% - 20px);
		}
	}
}
</style>
